package com.startup;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.type.JdbcType;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import com.baomidou.mybatisplus.MybatisConfiguration;
import com.baomidou.mybatisplus.MybatisXMLLanguageDriver;
import com.baomidou.mybatisplus.activerecord.Model;
import com.baomidou.mybatisplus.entity.GlobalConfiguration;
import com.baomidou.mybatisplus.enums.DBType;
import com.baomidou.mybatisplus.mapper.LogicSqlInjector;
import com.baomidou.mybatisplus.plugins.OptimisticLockerInterceptor;
import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.plugins.PerformanceInterceptor;
import com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean;
import com.onlyxiahui.query.mybatis.dao.GenericDAO;
import com.onlyxiahui.query.mybatis.dao.JdbcTemplate;
import com.startup.myplus.DatabaseType;
import com.startup.myplus.DynamicDataSource;
import com.startup.myplus.OIMObjectHandler;

@Configuration
@MapperScan({"com.im.server.general.manage.common.bean","com.im.server.general.manage.common.mapper"})
public class MybatisPlusConfig {

	@Autowired
	DataSourceConfig dataSourceConfig;

	/**
	 * mybatis-plus分页插件
	 */
	@Bean
	public PaginationInterceptor paginationInterceptor() {
		PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
		paginationInterceptor.setDialectType(DBType.MYSQL.getDb());
		return paginationInterceptor;
	}

	// @Bean(name = "masterDataSource")
	// @Qualifier("masterDataSource")
	// @ConfigurationProperties(prefix = "spring.datasource.master")
	// public DataSource masterDataSource() {
	// return DataSourceBuilder.create().build();
	// }
	//
	// @Bean(name = "slaveDataSource")
	// @Qualifier("slaveDataSource")
	// public DataSource slaveDataSource() {
	// DruidDataSource dataSource = new DruidDataSource();
	// druidProperties.coinfig(dataSource);
	//
	// return dataSource;
	// }

	/**
	 * 构造多数据源连接池 Master 数据源连接池采用 HikariDataSource Slave 数据源连接池采用 DruidDataSource
	 * 
	 * @param master
	 * @param slave
	 * @return
	 */
	@Bean
	public DynamicDataSource dataSource() {
		Map<Object, Object> targetDataSources = new HashMap<>();
		targetDataSources.put(DatabaseType.master, dataSourceConfig.writeDataSource());
		targetDataSources.put(DatabaseType.slave, dataSourceConfig.readDataSource());

		DynamicDataSource dataSource = new DynamicDataSource();
		dataSource.setTargetDataSources(targetDataSources);// 该方法是AbstractRoutingDataSource的方法
		dataSource.setDefaultTargetDataSource(dataSourceConfig.readDataSource());// 默认的datasource设置为myTestDbDataSourcereturn
		// dataSource;
		return dataSource;
	}

//	@Bean("mybatisSqlSession")
//	public SqlSessionFactory  sqlSessionFactory() throws Exception {
//        MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
//        sqlSessionFactory.setDataSource(this.dataSource());
//        sqlSessionFactory.setTypeAliasesPackage("com.im.server.general.manage.common.bean");
//       
//        MybatisConfiguration configuration = new MybatisConfiguration();
//        configuration.setDefaultScriptingLanguage(MybatisXMLLanguageDriver.class);
//        configuration.setJdbcTypeForNull(JdbcType.NULL);
//        sqlSessionFactory.setConfiguration(configuration);
//        //sqlSessionFactory.setConfigLocation(new ClassPathResource("mybatis-config.xml"));
//        sqlSessionFactory.setGlobalConfig(globalConfiguration());
//        sqlSessionFactory.setPlugins(new Interceptor[] {
//				new DatabasePlugin(),
//				paginationInterceptor(),
//				new PerformanceInterceptor(),
//				new OptimisticLockerInterceptor() });
//        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
//		try {
//			//sqlSessionFactory.setConfigLocation(new ClassPathResource("mybatis-config.xml"));
//			sqlSessionFactory.setMapperLocations(resolver.getResources("classpath*:/dao/manage/mybatis/mysql/*/*.xml"));
//		} catch (IOException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
//        return sqlSessionFactory.getObject();
//    }

	@Bean("mybatisSqlSession")
    public SqlSessionFactory sqlSessionFactory() throws Exception {
        MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
        sqlSessionFactory.setDataSource(this.dataSource());
        sqlSessionFactory.setTypeAliasesPackage("com.im.server.general.manage.common.bean");
        MybatisConfiguration configuration = new MybatisConfiguration();
        configuration.setDefaultScriptingLanguage(MybatisXMLLanguageDriver.class);
        configuration.setJdbcTypeForNull(JdbcType.NULL);
        configuration.addMappers("com.im.server.general.manage.common.bean",Model.class);
        
       // sqlSessionFactory.setConfiguration(configuration);
        sqlSessionFactory.setPlugins(new Interceptor[]{
                new PaginationInterceptor(),
                new PerformanceInterceptor(),
                new OptimisticLockerInterceptor()
        });
        sqlSessionFactory.setGlobalConfig(globalConfiguration());
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
		try {
			sqlSessionFactory.setConfigLocation(new ClassPathResource("mybatis-config.xml"));
			sqlSessionFactory.setMapperLocations(resolver.getResources("classpath*:/dao/manage/mybatis/mysql/*/*.xml"));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        return sqlSessionFactory.getObject();
    }
    
//	@Bean
//	@Primary
//	public MybatisSqlSessionFactoryBean sqlSessionFactory() throws Exception {
//		MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
//		bean.setDataSource(this.dataSource());
//		// 是否启动多数据源配置，目的是方便多环境下在本地环境调试，不影响其他环境
//		// if (druidProperties.getOnOff() == true) {
//		bean.setPlugins(new Interceptor[] {
//				new DatabasePlugin(),
//				paginationInterceptor(),
//				new PerformanceInterceptor(),
//				new OptimisticLockerInterceptor() });
//		// }
//		bean.setTypeAliasesPackage("com.im.server.general.manage.common.bean");
//		PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
//		try {
//			bean.setConfigLocation(new ClassPathResource("mybatis-config.xml"));
//			bean.setMapperLocations(resolver.getResources("classpath*:/dao/manage/mybatis/mysql/*/*.xml"));
//		} catch (IOException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
//		bean.setGlobalConfig(globalConfiguration());
//		return bean;
//	}

	// //////////////////////////////////////////写数据源

	// @Bean(name = "txManager")
	// public DataSourceTransactionManager txManager() {
	// DataSourceTransactionManager bean = new DataSourceTransactionManager();
	// bean.setDataSource(dataSourceConfig.writeDataSource());
	// return bean;
	// }

//	@Bean(name = "writeSqlSessionFactory")
//	public SqlSessionFactory writeSqlSessionFactory() {
//		SqlSessionFactory factory = null;
//		MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
//		bean.setDataSource(dataSourceConfig.writeDataSource());
//		bean.setTypeAliasesPackage("com.im.server.general.manage.common.bean");
//		MybatisConfiguration configuration = new MybatisConfiguration();
//		configuration.setDefaultScriptingLanguage(MybatisXMLLanguageDriver.class);
//		configuration.setJdbcTypeForNull(JdbcType.NULL);
//
//		configuration.addMappers("/");
//		bean.setConfiguration(configuration);
//		bean.setPlugins(new Interceptor[] {
//				new PaginationInterceptor(),
//				new PerformanceInterceptor(),
//				new OptimisticLockerInterceptor()
//		});
//		bean.setGlobalConfig(globalConfiguration());
//
//		//
//		// bean.setConfigLocation(new ClassPathResource("mybatis-config.xml"));
//		try {
//			factory = bean.getObject();
//		} catch (Exception e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
//		return factory;
//	}

	@Bean(name = "sqlSessionTemplate")
	public SqlSessionTemplate sqlSessionTemplate() {
		SqlSessionTemplate bean = null;
		try {
			bean = new SqlSessionTemplate(sqlSessionFactory());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return bean;
	}

	@Bean(name = "writeGenericDAO")
	public GenericDAO writeGenericDAO() {
		GenericDAO bean = new GenericDAO();
		bean.setSqlSessionTemplate(sqlSessionTemplate());
		return bean;
	}

	@Bean(name = "readGenericDAO")
	public GenericDAO readGenericDAO() {
		GenericDAO bean = new GenericDAO();
		bean.setSqlSessionTemplate(sqlSessionTemplate());
		return bean;
	}

	@Bean(name = "jdbcTemplate")
	public JdbcTemplate jdbcTemplate() {
		JdbcTemplate bean = new JdbcTemplate();
		bean.setDataSource(dataSourceConfig.writeDataSource());
		return bean;
	}

	@Bean
	public GlobalConfiguration globalConfiguration() {
		GlobalConfiguration conf = new GlobalConfiguration(new LogicSqlInjector());
		conf.setLogicDeleteValue("-1");
		conf.setLogicNotDeleteValue("1");
		conf.setIdType(2);
		conf.setDbColumnUnderline(false);//不启用下划线
		conf.setMetaObjectHandler(new OIMObjectHandler());
		return conf;
	}
}
